package com.aries.remoteplus.view;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.aries.remoteplus.R;
import com.aries.remoteplus.core.DiscoverThread.DiscoverListener;
import com.aries.remoteplus.core.DiscoverThread;
import com.aries.remoteplus.core.RPConstants;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;

public class ServersActivity extends Activity {
	
	private String serverName;
	private String ipAddress;
	private int tcpPort;
	private int udpPort;
	private String passWord; 
	
	private Intent addIntent;
	
	private DiscoverThread discoverThread;
	private Handler uiHandler;
	
	private ListView serverListView;
	private TextView serverTextView;
	
	private SharedPreferences ipPrefs;
	private SharedPreferences serverNamePrefs; 	
	private SharedPreferences tcpPortPrefs;
	private SharedPreferences udpPortPrefs;
	private SharedPreferences passWordPrefs;
	
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		this.setContentView(R.layout.servers);
		
		this.uiHandler = new Handler();
		
		ipPrefs				= this.getSharedPreferences(RPConstants.PREFS_IPKEY, Context.MODE_PRIVATE);
		serverNamePrefs 	= this.getSharedPreferences(RPConstants.PREFS_SERVER_NAME, Context.MODE_PRIVATE);
		tcpPortPrefs		= this.getSharedPreferences(RPConstants.PREFS_TCP_PORT, Context.MODE_PRIVATE);
		udpPortPrefs		= this.getSharedPreferences(RPConstants.PREFS_UDP_PORT, Context.MODE_PRIVATE);
		passWordPrefs		= this.getSharedPreferences(RPConstants.PREFS_PASSWORD, Context.MODE_PRIVATE);
		
		Button addButton = (Button) this.findViewById(R.id.add);
		Button rmvButton = (Button) this.findViewById(R.id.remove);
		this.serverListView = (ListView) this.findViewById(R.id.servers_list);
		this.serverTextView = (TextView) this.findViewById(android.R.id.empty);
		
		this.displayHosts();
		
		this.addIntent = new Intent(this.getApplicationContext(), AddServerActivity.class);
		
		addButton.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v)
			{
				// TODO Auto-generated method stub
				addButtonClickHandler();
			}
		});
		
		rmvButton.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) 
			{
				// TODO Auto-generated method stub
				Editor ipEditor = ipPrefs.edit();
				ipEditor.clear();
				ipEditor.commit();
				
				Editor serverNameEditor = serverNamePrefs.edit();
				serverNameEditor.commit();
				
				Editor tcpPortEditor = tcpPortPrefs.edit();
				tcpPortEditor.commit();
				
				Editor udpPortEditor = udpPortPrefs.edit();
				udpPortEditor.commit();
				
				Editor passWordEditor = passWordPrefs.edit();
				passWordEditor.commit();
				
				displayHosts();
			}
		});
		
		serverListView.setOnItemClickListener(new ListItemClickListener());
	}
	
	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data)
	{
		super.onActivityResult(requestCode, resultCode, data);
		
		if (requestCode == RPConstants.SUC_REQUESTCODE)
		{
			if (RESULT_OK == resultCode)
			{
				Bundle serverBundle = data.getExtras();
				  
				this.serverName 	= serverBundle.getString("serverName");
				this.ipAddress 		= serverBundle.getString("ipAddress");
				String tcpPortStr	= serverBundle.getString("tcpPort");
				String udpPortStr	= serverBundle.getString("udpPort");
				this.passWord		= serverBundle.getString("passWord");
				
				this.tcpPort = tcpPortStr.equals("") ? 57110 : Integer.parseInt(tcpPortStr);
				this.udpPort = udpPortStr.equals("") ? 57110 : Integer.parseInt(udpPortStr);
				this.serverName = serverName.equals("") ? "Unknown Server Name" : serverName;
				
				this.saveHost();
				this.displayHosts();
			}
		}
	}
	
	public void saveHost()
	{
		Map<String, String> ipMap = (Map<String, String>) this.ipPrefs.getAll();
		
		int serverNums = ipMap.size();
		
		if ( !ipMap.containsValue(ipAddress) )
		{
			Editor ipEditor 			= this.ipPrefs.edit();
			Editor serverNameEditor		= this.serverNamePrefs.edit();
			Editor tcpPortEditor		= this.tcpPortPrefs.edit();
			Editor udpPortEditor		= this.udpPortPrefs.edit();
			Editor passWordEditor		= this.passWordPrefs.edit();
			
			ipEditor.putString(RPConstants.RECENT_HOST + (++serverNums), this.ipAddress);
			ipEditor.commit();
			
			serverNameEditor.putString(RPConstants.RECENT_HOST + serverNums, this.serverName);
			serverNameEditor.commit();
			
			tcpPortEditor.putInt(RPConstants.RECENT_HOST + serverNums, this.tcpPort);
			tcpPortEditor.commit();
			
			udpPortEditor.putInt(RPConstants.RECENT_HOST + serverNums, this.udpPort);
			udpPortEditor.commit();
			
			passWordEditor.putString(RPConstants.RECENT_HOST + serverName, this.passWord);
			passWordEditor.commit();	
		}
	}
	
	public void displayHosts()
	{
		Map<String, String> ipMap				= (Map<String, String>) this.ipPrefs.getAll();
		Map<String, String> serverNameMap		= (Map<String, String>) this.serverNamePrefs.getAll();
		Map<String, Integer> tcpPortMap			= (Map<String, Integer>) this.tcpPortPrefs.getAll();
		
		List<Map<String, Object>> dataList = new ArrayList<Map<String,Object>>();
		
		if (ipMap.size() != 0)
		{
			this.serverTextView.setVisibility(View.GONE);
		}
		else 
		{
			this.serverTextView.setVisibility(View.VISIBLE);
		}
		
		for (int i = 0; i < ipMap.size(); i++)
		{
			Map<String, Object> dataMap = new HashMap<String, Object>();
			
			String savedIP 				= ipMap.get(RPConstants.RECENT_HOST + (i+1));
			String savedServerName		= serverNameMap.get(RPConstants.RECENT_HOST + (i+1));
			Integer savedTcpPort		= tcpPortMap.get(RPConstants.RECENT_HOST + (i+1));
			
			dataMap.put("serverName", savedServerName);
			dataMap.put("ipAddressPort", savedIP + ":" + savedTcpPort);
			dataMap.put("icon", R.drawable.ic_wifi);
			
			dataList.add(dataMap);
		}
		
		SimpleAdapter listViewAdapter = new SimpleAdapter(this, dataList, R.layout.list_item, 
												new String[] {"serverName", "ipAddressPort", "icon"}, 
												new int[] {R.id.text_title, R.id.text_hint, R.id.icon});
		
		this.serverListView.setAdapter(listViewAdapter);
	}
	
	private class ListItemClickListener implements OnItemClickListener
	{

		@Override
		public void onItemClick(AdapterView<?> parent, View view, int position,
				long id)
		{
			// TODO Auto-generated method stub
			Intent dataIntent = new Intent();
			
			String currentIP				= ipPrefs.getString(RPConstants.RECENT_HOST + (position+1), "");
			String currentServerName		= serverNamePrefs.getString(RPConstants.RECENT_HOST + (position+1), "Unknown Server Name");
			Integer currentTcpPort			= tcpPortPrefs.getInt(RPConstants.RECENT_HOST + (position+1), 9527);
			Integer currentUdpPort			= udpPortPrefs.getInt(RPConstants.RECENT_HOST + (position+1), 9527);
			String currentPassWord			= passWordPrefs.getString(RPConstants.RECENT_HOST + (position+1), "");
			
			dataIntent.putExtra("currentIP", currentIP);
			dataIntent.putExtra("currentServerName", currentServerName);
			dataIntent.putExtra("currentTcpPort", currentTcpPort);
			dataIntent.putExtra("currentUdpPort", currentUdpPort);
			dataIntent.putExtra("currentPassWord", currentPassWord);
			
			setResult(RESULT_OK, dataIntent);
			finish();
		}
		
	}
	
	private void addButtonClickHandler()
	{
		AlertDialog.Builder dialogBuilder 	= new AlertDialog.Builder(this);
		dialogBuilder.setTitle("Add Server");
		dialogBuilder.setItems(R.array.diag_server_scan_entries, new OnClickListener() {
			
			@Override
			public void onClick(DialogInterface dialog, int which)
			{
				// TODO Auto-generated method stub
				if (which == 0)
				{
					if (discoverThread == null)
					{
						discoverThread = new DiscoverThread(new DiscoverListener() {
							
							@Override
							public void onAddressReceived(String tServerName, String address, int port)
							{
								// TODO Auto-generated method stub
								serverName 	= tServerName;
								ipAddress	= address;
								udpPort		= port;
								tcpPort		= port;
								
								saveHost();
								
								uiHandler.post(new Runnable() {
									
									@Override
									public void run()
									{
										// TODO Auto-generated method stub
										displayHosts();
									}
								});
							}
						});
						if ( !discoverThread.isAlive() )
						{
							discoverThread.start();
						}
					}
					else 
					{
						try
						{
							discoverThread.sendIDRequest();
						} catch (IOException e)
						{
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (InterruptedException e)
						{
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}
				else if (which == 1)
				{
					startActivityForResult(addIntent, RPConstants.SUC_REQUESTCODE);
				}
			}
		});
		
		AlertDialog typeDialog = dialogBuilder.create();
		typeDialog.show();
	}
}
